/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.spark.h2o.utils

import org.scalatest.{Canceled, FunSuite, Outcome}

/**
  * Base class for H2O tests
  * These tests can be aborted.
  *
  * Idea: Eugene Zhulenev, http://stackoverflow.com/questions/26001795/how-to-configure-scalatest-to-abort-a-suite-if-a-test-fails
  */
trait TestBase extends FunSuite {
  import TestBase._

  override def withFixture(test: NoArgTest): Outcome = {
    if (aborted) {
      Canceled(s"Canceled because $explanation")
    }
    else {
      super.withFixture(test)
    }
  }

  def abort(text: String = "one of the tests failed"): Unit = {
    aborted = true
    explanation = text
  }

  def abort(exception: Throwable): Unit = {
    val root: Throwable = Stream.iterate(exception)(_.getCause).dropWhile(_.getCause != null).head

    abort(root.getMessage)
  }
}

object TestBase {
  @volatile var aborted = false
  @volatile var explanation = "nothing happened"
}
